package fr.lip6.meta.ple.featureIdentification;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import fr.lip6.meta.tools.Trigger;

public class MoreFrequentTrigger implements FeaturePriorityStrategy {

	@Override
	public Collection<Trigger> chooseFeatureToMerge(Collection<? extends Feature>
			features) {
		
		Feature toMerge = new Feature();
		if (features.isEmpty()) return toMerge;
		
		Trigger t = searchMostRepeated(features);
		return (t == null ? toMerge : getMaxSet(features, t));
	}
	
	/**
	 * Counts the repetitions of a trigger in a collection
	 * @param c - the collection of triggers
	 * @param o - the trigger
	 * @return the number of repetitions
	 */
	private static int countRepetitions (Collection<Trigger> c, Trigger o) {
		int nRep = 0;
		for (Trigger t : c)
			if (t.equals(o))
				nRep++;
		return nRep;
	}
	
	/**
	 * Looks for the most repeated trigger in a set of features
	 * @param features - a collection of features
	 * @return the most repeated trigger
	 */
	private Trigger searchMostRepeated (Collection<? extends Feature>
			feature) {
		
		//Search the number of repetitions for each trigger
		ArrayList<Trigger> allTriggers = new ArrayList<Trigger>();
		for (Feature s : feature)
			for (Trigger t : s)
				allTriggers.add(t);
		
		//Return the most repeated
		Trigger mostRepeated = null;
		int nRep = -1;
		for (Trigger t : allTriggers) {
			int n = countRepetitions(allTriggers, t);
			if (n > nRep) {
				nRep = n;
				mostRepeated = t;
			}
		}
		
		return (nRep < 2 ? null : mostRepeated);
	}
	
	/**
	 * Searches the maximum set that can be constructed containing the trigger
	 * in a collection of features
	 * @param features - the collection of features
	 * @param t - a trigger
	 * @return a feature containing the given triggers, and the others that
	 * appears always in the collection of features with this one.
	 */
	private Collection<Trigger> getMaxSet(Collection<? extends Feature> features,
			Trigger t) {
		
		List<Feature> compatibles = new ArrayList<Feature>();
		for (Feature s : features) {
			if (s.contains(t))
				compatibles.add(s);
		}
		
		return Feature.getCommonLine(compatibles);
	}

}
